package cl.gob.minvu.catastro.ejb.imp;

import java.util.LinkedList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.jboss.logging.Logger;

import cl.gob.minvu.catastro.ejb.UsuarioEJBRemote;
import cl.gob.minvu.catastro.model.Usuario;
import cl.gob.minvu.catastro.util.PasswordManager;

/**
 * @author psep
 *
 */
@Stateful
@LocalBean
public class UsuarioEJB implements UsuarioEJBRemote {
	
	private static final Logger logger = Logger.getLogger(UsuarioEJB.class);

	@PersistenceContext(unitName = "appCatastro")
	private EntityManager em;

	@PostConstruct
	private void init() {
	}

	@Override
	public Usuario find(Usuario usuario) {
		Usuario user = null;
		
		try {
			String sql = "SELECT u FROM Usuario u WHERE u.username = :nombreusuario AND u.password = :contrasenia";
			
			Query query = em.createQuery(sql);
			query.setParameter("nombreusuario", usuario.getUsername());
			query.setParameter("contrasenia", PasswordManager.encrypt(usuario.getPassword()));
			
			user = (Usuario) query.getSingleResult();
			
		} catch (Exception e) {
			logger.info("Usuario no encontrado");
		}
		
		return user;
	}

	@Override
	public List<Usuario> list(Usuario usuario) {
		List<Usuario> usuarios = new LinkedList<Usuario>();
		
		try {
			usuarios = em.createQuery("SELECT u FROM Usuario u", Usuario.class).getResultList();
		} catch (Exception e) {
			logger.error(e, e);
		}
		
		return usuarios;
	}

	@Override
	public Boolean save(Usuario usuario) {
		boolean result = false;
		
		try {
			em.persist(usuario);
			result = true;
			
		} catch (Exception e) {
			logger.error(e, e);
		}
		
		return result;
	}

	@Override
	public Boolean update(Usuario usuario) {
		boolean result = false;
		
		try {
			Usuario user = em.getReference(Usuario.class, usuario.getIdusuario());
			user.getPersona().setNombres(usuario.getPersona().getNombres());
			user.getPersona().setApellidopaterno(usuario.getPersona().getApellidopaterno());
			user.getPersona().setApellidomaterno(usuario.getPersona().getApellidomaterno());
			user.setUsername(usuario.getUsername());
			user.setPassword(usuario.getPassword());
			result = true;
			
		} catch (Exception e) {
			logger.error(e, e);
		}
		
		return result;
	}

	@Override
	public Boolean delete(Usuario usuario) {
		boolean result = false;
		
		try {
			Usuario userRemove = em.getReference(Usuario.class, usuario.getIdusuario());
			em.remove(userRemove);
			em.flush();
			result = true;
			
		} catch (Exception e) {
			logger.error(e, e);
		}
		
		return result;
	}

	@Override
	public int countByUser(Usuario usuario) {
		int count = 0;
		
		try {
			Query sql = em
					.createQuery("SELECT COUNT(u) FROM Usuario u JOIN u.persona p WHERE p.rut = :rut");
			sql.setParameter("rut", usuario.getPersona().getRut());
			int countByRun = ((Long) sql.getSingleResult()).intValue();
			
			Query sql2 = em.createQuery("SELECT COUNT(u) FROM Usuario u WHERE u.username = :username");
			sql2.setParameter("username", usuario.getUsername());
			int countByUsername = ((Long) sql2.getSingleResult()).intValue();
			
			count = countByRun + countByUsername;

		} catch (Exception e) {
			logger.error(e, e);
		}
		
		return count;
	}

}
